解决使用 Python 的 matplotlib 画图时中文显示为乱码的问题 | J. Xu
在使用 Python
的 matplotlib
画图时如果设置了标题或者坐标轴名称为中文时,显示图片上中文出现乱码或四边形,不能正常显示我们需要的中文字,体验非常不好。下面给出一个解决方法。本篇以 Linux (Debian)系统为例。
可以在 wfonts 下载,也可以在其他任何能够下载到 SimHei.ttf
的地方下载。
把字体放在 matplotlib
能够发现的位置,如何指导正确的位置
➜ ~ ipython
Python 3.8.5 (default, Sep 4 2020, 07:30:14)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.23.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import matplotlib
In [2]: matplotlib.matplotlib_fname()
Out[2]: '/usr/local/miniconda/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc'
从上面可以发现一个目录:'/usr/local/miniconda/lib/python3.8/site-packages/matplotlib/mpl-data/'
,在该目录下有个文件夹
➜ ~ ls /usr/local/miniconda/lib/python3.8/site-packages/matplotlib/mpl-data
fonts images matplotlibrc plot_directive sample_data stylelib
➜ ~ ls /usr/local/miniconda/lib/python3.8/site-packages/matplotlib/mpl-data/fonts
afm pdfcorefonts ttf
把下载的 SimHei.ttf
拷贝到 ttf
文件夹下
一般需要先清除掉旧的 matplotlib
缓存后才能正常使用,缓存一般在家目录下,可以通过如下方法获得缓存地址
➜ ~ ipython
Python 3.8.5 (default, Sep 4 2020, 07:30:14)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.23.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import matplotlib
In [2]: matplotlib.get_cachedir()
Out[2]: '/home/jinzhongxu/.cache/matplotlib'
发现我的确实在家目录下,因此直接去家目录删除即可
➜ ~ ls .cache
jedi matplotlib yarn
➜ ~ ls .cache/matplotlib
fontlist-v330.json
➜ ~ rm -r ~/.cache/matplotlib
配置好中文字体后,只需要在每次画图时指定字体就可以正常显示中文字符了。
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
x = np.linspace(-5, 5, 101)
y = np.cos(x)
plt.plot(x, y, "r")
plt.title(u"余弦")
plt.show()
从上面可知,每次画图都需要在代码中配置中文字体才能正常显示中文字符,下面通过设置可以直接使用中文字体,那就是修改上面的配置文件
vim /usr/local/miniconda/lib/python3.8/site-packages/matplotlib/mpl-data/matplotlibrc
font.family : sans-serif
font.sans-serif : SimHei, Bitstream Vera Sans, ...
axes.unicode_minus : False
import matplotlib.pyplot as plt
import numpy as np
a = 3
x = np.linspace(-(a + 1) * np.pi / 4, (a + 1) * np.pi / 4, 301)
y1 = a * (1 + np.cos(x)) * np.cos(x)
y2 = a * (1 + np.cos(x)) * np.sin(x)
fig, ax = plt.subplots()
for key, spine in ax.spines.items():
spine.set_visible(False)
plt.plot(y2, -y1)
plt.xticks([])
plt.yticks([])
plt.axis("equal")
plt.show()
整体调整
import matplotlib
font = {"family": "SimHei", "weight": "bold", "size": 20}
matplotlib.rc("font", **font)
import matplotlib
matplotlib.rcParams.update({'font.size': 20})
import matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 20})
单个调整
import matplotlib
SIZE = 20
matplotlib.rc('font', size=SIZE)
matplotlib.rc('axes', titlesize=SIZE)
import matplotlib.pyplot as plt
SIZE = 20
plt.rc('font', size=SIZE)
plt.rc('axes', titlesize=SIZE)
plt.rc('axes', labelsize=SIZE)
plt.rc('xtick', labelsize=SIZE)
plt.rc('ytick', labelsize=SIZE)
plt.rc('legend', fontsize=SIZE)
plt.rc('figure', titlesize=SIZE)